DeriveGamemode('frettabox_base')
include( 'shared.lua' )
include( 'tables.lua' )
include( 'admin.lua' )
include( 'inventories.lua' )
include( 'awards.lua' )
include( 'cl_spawnmenu.lua' )
include( 'cl_postprocess.lua' )
include( 'cl_scoreboard.lua' )
include( 'cl_hudpickup.lua' )
include( 'cl_deathnotice.lua' )
include( 'cl_notice.lua' )
include( 'cl_hudstains.lua' )

function GM:Initialize( )	

	self.BaseClass:Initialize()
	GAMEMODE:SetupTeams()
	
	WindVector = Vector(math.random(-15,15),math.random(-15,15),0) //fake wind velocity 4 dem clientside effects
	
	ToggleMusic,TogglePP,ToggleFVOX,ToggleHUD = true,true,true,true
	MaxHealth = 1
	CureTime = 0
	EvacTime = 0
	Unlocked = 0.2
	CurMenu = nil
	
	GameInfo.cInv = {}
	
	surface.CreateFont("Tahoma", 14, 500, true, false, "HudText")
	surface.CreateFont("Tahoma", 12, 500, true, false, "HudTextSmall")
	surface.CreateFont("Tahoma", 16, 500, true, false, "HelpText")
	surface.CreateFont("Typenoksidi", 14, 500, true, false, "HudInfo" )
	surface.CreateFont("Typenoksidi", 20, 500, true, false, "HudInfoBig" )
	surface.CreateFont("Mortbats", 32, 500, true, false, "HazInfo" )
	
	//font colors
	color_red = Color(220, 40, 40, 245)
	color_blue = Color(40, 40, 220, 245)
	color_red_t = Color(220, 40, 40, 190)
	color_blue_t = Color(40, 40, 220, 190)
	color_lightred = Color(210, 100, 100, 255)
	color_lightblue = Color(100, 100, 210, 255)
	color_white = Color(255,255,255,255)
	color_white_t = Color(255,255,255,155)
	color_green = Color(50,255,50,255)

end

function DrawPlayerEffects()
	if TogglePP == false then return end
	
	Hazard.Bleeding = LocalPlayer():GetNetworkedBool("bleeding",false)
	Hazard.Poisoned = LocalPlayer():GetNetworkedBool("poisoned",false)
	Hazard.Infected = LocalPlayer():GetNetworkedBool("infected",false)
	Hazard.Blinded = LocalPlayer():GetNetworkedBool("blinded",false)
	Hazard.Fire = LocalPlayer():GetNetworkedBool("onfire",false)
	local hpratio = LocalPlayer():Health() / MaxHealth
	
	if LocalPlayer():Team() == TEAM_UNDEAD then 
		if LocalPlayer():Alive() then
			ColorModify[ "$pp_colour_brightness" ] 	= -.20
			ColorModify[ "$pp_colour_addr" ]		= .25
			ColorModify[ "$pp_colour_mulr" ] 		= .15
			ColorModify[ "$pp_colour_addg" ]		= .20
			if Infravision then
				local pos = LocalPlayer():GetPos()
				for _, ply in pairs(player.GetAll()) do
					if ply:Team() == TEAM_HUMANS and ply:Alive() then
						local trgpos = ply:GetPos() + Vector(0,0,50)
						if trgpos:Distance(pos) < 4000 then
							local vel = ply:GetVelocity() * 0.6
							local emitter = ParticleEmitter(trgpos)
							for i=1, math.random(2,3) do
								local par = emitter:Add("Sprites/light_glow02_add_noz.vmt", trgpos)
								par:SetVelocity(vel + Vector(math.random(-25, 25),math.random(-25, 25), math.Rand(-20, 20)))
								par:SetDieTime(0.5)
								par:SetStartAlpha(4)
								par:SetEndAlpha(2)
								par:SetStartSize(math.random(2, 9))
								par:SetEndSize(math.random(1,7))
								par:SetColor(220, math.random(50,115), 10) //par:SetColor(220, 10, 10)
								par:SetRoll(math.random(0, 300))
							end
							emitter:Finish()
						end
					end
				end
			else
				for k,v in pairs(team.GetPlayers(TEAM_HUMANS)) do
					v:SetMaterial("")
				end	
			end
		else
			ColorModify[ "$pp_colour_addr" ]		= .25
			ColorModify[ "$pp_colour_mulr" ] 		= .30
			ColorModify[ "$pp_colour_addg" ]		= .06
			ColorModify[ "$pp_colour_brightness" ] 	= -.22
			MotionBlur = .55
			Sharpen = 1.5
		end
		return
	end
	
	if not LocalPlayer():Alive() then
		ColorModify[ "$pp_colour_addr" ]		= .25
		ColorModify[ "$pp_colour_mulr" ] 		= .30
		ColorModify[ "$pp_colour_addg" ]		= .05
		ColorModify[ "$pp_colour_brightness" ] 	= -.22
		MotionBlur = .55
		Sharpen = 1.5
		return
	end
	
	local pos = LocalPlayer():GetPos()
	for k, ply in pairs(team.GetPlayers(TEAM_HUMANS)) do
		if ply:Alive() then
			local trgpos = ply:GetPos()
			if trgpos:Distance(pos) > 1000 then
				ply:SetMaterial("ReDead/allyvision")
			else
				ply:SetMaterial("")
			end
		end
	end
	
	if Hazard.Blinded then
		ColorModify[ "$pp_colour_brightness" ] 	= math.Approach( ColorModify[ "$pp_colour_brightness" ], -0.35, FrameTime() * 1.05 )
		ColorModify[ "$pp_colour_colour" ] = 1 * math.Clamp(hpratio,.25,.50)
		ColorModify[ "$pp_colour_mulr" ] = .45 * (1 - hpratio)
		MotionBlur = .60
		return
	end
	
	if Hazard.Fire then
		ColorModify[ "$pp_colour_addr" ] = .25
		ColorModify[ "$pp_colour_mulr" ] = .35 + (.15 * (1 - hpratio))
		ColorModify[ "$pp_colour_addg" ] = .13
		MotionBlur = .6 * (1 - hpratio)
		return
	end
	
	if Hazard.Poisoned then
		ColorModify[ "$pp_colour_brightness" ] 	= -.30 * (1 - math.Clamp(hpratio,.5,1))
		ColorModify[ "$pp_colour_addg" ] = .35 * (1 - hpratio)
		ColorModify[ "$pp_colour_mulg" ] = .30 * (1 - hpratio)
		ColorModify[ "$pp_colour_addr" ] = .25 * (1 - hpratio)
		MotionBlur = .8 * (1 - hpratio)
		return
	end
	
	if Hazard.Infected then
		ColorModify[ "$pp_colour_brightness" ] 	= -.25 * (1 - math.Clamp(hpratio,.5,1))
		ColorModify[ "$pp_colour_addg" ] = .25 * (1 - hpratio)
		ColorModify[ "$pp_colour_mulg" ] = .25 * (1 - hpratio)
		ColorModify[ "$pp_colour_addr" ] = .25 * (1 - hpratio)
		MotionBlur = .7 * (1 - hpratio)
		return
	end
	
	if Hazard.Bleeding then
		ColorModify[ "$pp_colour_addr" ] = .25 * (1 - hpratio)
		ColorModify[ "$pp_colour_mulr" ] = .35 * (1 - hpratio)
		MotionBlur = .6 * (1 - hpratio)
		return
	end
	
	Sharpen = 3.5 * (1 - hpratio)
	ColorModify[ "$pp_colour_colour" ] = 1 * math.Clamp(hpratio,.30,1)
	ColorModify[ "$pp_colour_mulr" ] = .55 * (1 - hpratio)
	
end
hook.Add( "RenderScreenspaceEffects", "DrawPlayerEffects", DrawPlayerEffects )

function GM:Think()
	if LocalPlayer() then
		CheckerTimer = CheckerTimer or CurTime() + 5
		if LocalPlayer():IsValid() and not SpawnClassVgui and LocalPlayer():GetNWBool("HasSeenSplash") == true then
			if LocalPlayer():GetNetworkedString("classdisable","dicks") != "dicks" then
				if LocalPlayer():Team() != TEAM_UNDEAD then
					RunConsoleCommand("derma_skin","ReDead_1")
					ClassVguiMenu()
				end
				SpawnClassVgui = true
			end
		end
		for k,ragdoll in pairs(ents.FindByClass("prop_ragdoll")) do
			if ragdoll:GetNWBool("headless",false) then
				function ragdoll:BuildBonePositions(numbones,numphysbones)
					local bone = 6
					local matrix = self:GetBoneMatrix(bone)
					matrix:Scale(Vector(0,0,0))
					self:SetBoneMatrix(bone,matrix)
				end
			end
		end
		if not LocalPlayer():Alive() and CheckerTimer < CurTime() then
			if CurMenu then
				CurMenu:Remove()
				gui.EnableScreenClicker(false)
				CurMenu = nil
			end
		end
	end
end	

local RDS = {}
function RDS:DrawGenericBackground( x, y, w, h, color )
 
   surface.SetDrawColor( 100, 0, 0, 115 )
   surface.DrawRect( x, y, w, h )
  
   surface.SetDrawColor( 255, 100, 0, 220 )
   surface.DrawOutlinedRect( x, y, w, h )
   surface.SetDrawColor( 255, 100, 0, 130 )
   surface.DrawOutlinedRect( x+1, y+1, w-2, h-2 )
   surface.SetDrawColor( 255, 100, 0, 100 )
   surface.DrawOutlinedRect( x+2, y+2, w-4, h-4 )
   surface.SetDrawColor( 255, 60, 0, 70 )
   surface.DrawOutlinedRect( x+4, y+4, w-8, h-8 )
   
end
derma.DefineSkin( "ReDead_1", "The ReDead Derma Skin", RDS )

local WalkTimer = 0
local VelSmooth = 0
function GM:CalcView( ply, origin, angle, fov )

	local vel = ply:GetVelocity()
	local ang = ply:EyeAngles()
	
	local corpse = LocalPlayer():GetNetworkedEntity("corpse")
	if corpse then
		if corpse:IsValid() and not LocalPlayer():Alive() then
			local headpos = corpse:LookupAttachment("eyes")
			local att = corpse:GetAttachment(headpos)
			if att == nil then
				att = {}
				att.Ang = ang
				att.Pos = corpse:GetPos() + Vector(0,0,20)
			end
			local view = {}
			view.origin = att.Pos + (att.Ang:Forward() * 1.2)
			view.angles = att.Ang
			return view
		end
	end
	
	if ply:GetGroundEntity() != NULL then	
		angle.roll = angle.roll + math.sin( WalkTimer ) * VelSmooth * 0.001
		angle.pitch = angle.pitch + math.sin( WalkTimer * 0.3 ) * VelSmooth * 0.001
	end
	
	VelSmooth = VelSmooth * 0.5 + vel:Length() * 0.05
	WalkTimer = WalkTimer + VelSmooth * FrameTime() * 0.05
	
	angle.roll = angle.roll + ang:Right():DotProduct( vel ) * 0.005
		
	return self.BaseClass:CalcView( ply, origin, angle, fov )
end

function GetCorpseHeadPositions( ent )
	local bonelist = {"Charple2.Head", "Charple3.Head", "Charple4.Head"}
	local head = ent:LookupBone( "ValveBiped.Bip01_Head1" )	
	if head == nil and ent:GetBoneMatrix(head) == nil then 
		for k,v in pairs(bonelist) do
			head = ent:LookupBone(v)
			if head != nil and ent:GetBoneMatrix(head) != nil then
				DebugMsg(v)
				return ent:GetBoneMatrix(head)
			end
		end
	else
		return ent:GetBoneMatrix(head)
	end	
end

function UpdateRedScore( msg )
	local num = msg:ReadShort()
	RedScore = num
end
usermessage.Hook("UpdateRedScore",UpdateRedScore) 

function GM:PostProcessPermitted( name )
	return false
end

function GM:PlayerBindPress( ply, bind, pressed )
	if not pressed then return false end
	if bind == "toggle_zoom" then
		return true
	end
	if bind == "impulse 100" and LocalPlayer():Team() != TEAM_HUMANS then
		return true
	end
end

w = ScrW()
h = ScrH()

HealthBox = {}
HealthBox.Black = Color(40, 40, 40, 200)
HealthBox.Black2 = Color(60, 60, 60, 200)
HealthBox.Black3 = Color(130, 130, 130, 250)
HealthBox.Border = .01
HealthBox.Border2x = .02
HealthBox.Width = .10
HealthBox.Height = HealthBox.Width + .02
HealthBox.StartY = .86
HealthBox.StartX = .02

Hazard = {}
Hazard.Bleeding = false
Hazard.Infect = false
Hazard.Poison = false
Hazard.Fire = false
Hazard.Red = Color(200,10,0,200)
Hazard.Green = Color(0,90,0,200)
Hazard.Blue = Color(0,10,100,200) //burn
Hazard.Purple = Color(100,0,200,200)

Points = {}
Points.StartX = .01
Points.StartY = HealthBox.StartY - .05
Points.Width = HealthBox.Width + .02
Points.Height = .03

Meters = {}
Meters.Spacer = .01
Meters.Ammo = {}
Meters.Ammo.Color = Color(100,150,0,90)
Meters.Ammo.StartX = HealthBox.StartX + HealthBox.Width + Meters.Spacer
Meters.Ammo.StartY = HealthBox.StartY + (HealthBox.Height*.66) + HealthBox.Border
Meters.Ammo.Width = .16
Meters.Ammo.Height = HealthBox.Height*.33
Meters.Stam = {}
Meters.Stam.Color = Color(0,50,150,90)
Meters.Stam.StartX = Meters.Ammo.StartX
Meters.Stam.StartY = HealthBox.StartY + (HealthBox.Height*.33)
Meters.Stam.Width = .14
Meters.Stam.Height = Meters.Ammo.Height
Meters.Inv = {}
Meters.Inv.Color = Color(0,150,100,90)
Meters.Inv.StartX = Meters.Ammo.StartX
Meters.Inv.StartY = HealthBox.StartY - HealthBox.Border 
Meters.Inv.Width = .12
Meters.Inv.Height = Meters.Ammo.Height

ZombieHealth = {}
ZombieHealth.Border = .01
ZombieHealth.Width = .15
ZombieHealth.Height = .05
ZombieHealth.StartY = .93
ZombieHealth.StartX = .02

function FindInvOrder(pos,size) 
	local start = pos
	local order = {}
	for i=1,math.Clamp(size,0,5) do
		pos = pos + 1 
		if pos > size then
			pos = 1
		end
		order[i] = pos
		if pos == start then return order end
	end
	return order
end

function SetInvPos( msg )
	InvPos = msg:ReadShort()
end
usermessage.Hook("cSetInvPos", SetInvPos) 

function SetFuncPos( msg )
	FuncPos = msg:ReadShort()
end
usermessage.Hook("cSetFuncPos", SetFuncPos) 

function HUDPaint()

	if not ToggleHUD then return end
	if !LocalPlayer():Alive() then return end
	if LocalPlayer():Team() == TEAM_SPECTATOR then return end
	
	//GAME INFO FOR ALL TEAMS
	draw.RoundedBox(0, w*.01, h*.01, w*.102, h*.05, Color(10, 10, 10, 140))
	draw.DrawText("Humans Left:  "..team.NumPlayers(TEAM_HUMANS), "HudInfo", w*.02, h*.018, color_white,0)
	draw.DrawText("Time Left:  "..TimeFormat(CurTime(),GameInfo.STime), "HudInfo", w*.02, h*.038, color_white,0)

	if LocalPlayer():Team() == TEAM_HUMANS then 
	
		//INVENTORY SHIT (this hook is a lot more stable than the SWEP hook)
		
		if LocalPlayer():GetActiveWeapon():IsValid() and LocalPlayer():GetActiveWeapon() != NULL then
			if LocalPlayer():GetActiveWeapon():GetPrintName() == "Inventory" then
			
				OldInvPos = OldInvPos or InvPos
				
				if OldInvPos != InvPos then //keep updating the position!
					OldInvPos = InvPos
					if GameInfo.cProps then
						for k,v in pairs(GameInfo.cProps) do
							if v:IsValid() then
								v:Remove()
							end
						end
						GameInfo.cProps = nil
					end
				end
				
				local order = FindInvOrder(OldInvPos,table.Count(GameInfo.cInv))
				
				//ITEM ICONS
				if not GameInfo.cProps then
					GameInfo.cProps = {}
					for k,v in pairs(order) do
						if k == 1 then
							if string.find(GameInfo.cInv[v],"weapons/") then
								GameInfo.InvTbl = {}
								GameInfo.InvTbl.Functions = {Inventory.DropWeapon}
								GameInfo.InvTbl.Name = "Weapon"
							else
								GameInfo.InvTbl = {}
								GameInfo.InvTbl.Functions = {Inventory.Drop,Inventory.Give} 
								local other = Inventory.FindTable(GameInfo.cInv[v])
								table.Add(GameInfo.InvTbl.Functions,other.Functions)
								GameInfo.InvTbl.Name = other.Name
							end
						end
						GameInfo.cProps[k] = vgui.Create("SpawnIcon")
						GameInfo.cProps[k]:SetSize(w*InvBox.Width,h*InvBox.Height)
						GameInfo.cProps[k]:SetPos(w*(InvBox.StartX+.001), h*PropPos[k])
						GameInfo.cProps[k]:SetModel(GameInfo.cInv[v])
					end
				end
			else
				if GameInfo.cProps then
					for k,v in pairs(GameInfo.cProps) do
						if v:IsValid() then
							v:Remove()
						end
					end
				GameInfo.cProps = nil
				end
			end
		end
	
		local pos = LocalPlayer():GetNetworkedVector("antidotepos") 
		local sc = pos:ToScreen()
		if sc.visible then
			local dist = math.Round(LocalPlayer():GetPos():Distance(pos) / 16) //16 units per foot
			draw.DrawText("x", "HudInfo", sc.x, sc.y, color_red,1,1)
			draw.DrawText(TimeFormat(CurTime(),CureTime), "HudInfo", sc.x, sc.y + 16, color_white,1,1)
			draw.DrawText(dist.." feet", "HudInfo", sc.x, sc.y + 28, color_white,1,1)
		end
		
		local hp = LocalPlayer():Health()
		local hpratio = hp/MaxHealth
		local hpred=255*(1-hpratio)
		local hpgreen=200*hpratio
		local hpblue =40*hpratio
		local hpcolor = Color(hpred,hpgreen,hpblue,130)
		
		local drawh = ((h*HealthBox.Height)/ MaxHealth)*hp 
		
		//HEALTH METER
		draw.RoundedBox( 0, w*(HealthBox.StartX+.001), h*.98 - drawh, w*(HealthBox.Width-.001), drawh - (h * .002), hpcolor )
		
		//HEALTH BOX MEDIC SHAPED THING
		//left top
		draw.RoundedBox(0, w*(HealthBox.StartX+.001), h*HealthBox.StartY, w*(HealthBox.Width*.33), h*(HealthBox.Height*.33), HealthBox.Black3 ) 
		//right top
		draw.RoundedBox(0, w*(HealthBox.StartX+(HealthBox.Width*.66)+.001), h*HealthBox.StartY, w*(HealthBox.Width*.33), h*(HealthBox.Height*.33), HealthBox.Black3 ) 
		//left bottom
		draw.RoundedBox(0, w*(HealthBox.StartX+.001), h*(HealthBox.StartY+(HealthBox.Height*.66)), w*(HealthBox.Width*.33), h*(HealthBox.Height*.33), HealthBox.Black3 )
		//right bottom
		draw.RoundedBox(0, w*(HealthBox.StartX+(HealthBox.Width*.66)+.001), h*(HealthBox.StartY+(HealthBox.Height*.66)), w*(HealthBox.Width*.33), h*(HealthBox.Height*.33), HealthBox.Black3 )
		//left borderwall
		draw.RoundedBox(0, w*(HealthBox.StartX-HealthBox.Border), h*(HealthBox.StartY-HealthBox.Border), w*HealthBox.Border, h*(HealthBox.Height+HealthBox.Border2x-.001), HealthBox.Black2 ) 
		//right borderwall
		draw.RoundedBox(0, w*(HealthBox.StartX+HealthBox.Width), h*(HealthBox.StartY-HealthBox.Border), w*HealthBox.Border, h*(HealthBox.Height+HealthBox.Border2x-.001), HealthBox.Black2 ) 
		//top borderwall
		draw.RoundedBox(0, w*(HealthBox.StartX+.001), h*(HealthBox.StartY-HealthBox.Border), w*(HealthBox.Width-.001), h*HealthBox.Border, HealthBox.Black2 ) 
		//bottom borderwall
		draw.RoundedBox(0, w*(HealthBox.StartX+.001), h*(HealthBox.StartY+HealthBox.Height-.002), w*(HealthBox.Width-.001), h*HealthBox.Border, HealthBox.Black2 ) 
		
		//HAZARD STATUS METER
		//draw.RoundedBox(0, w*StatusBox.StartX, h*StatusBox.StartY, w*StatusBox.Width, h*StatusBox.Height, HealthBox.Black ) 
		
		Hazard.Bleeding = LocalPlayer():GetNetworkedBool("bleeding",false)
		Hazard.Poisoned = LocalPlayer():GetNetworkedBool("poisoned",false)
		Hazard.Infected = LocalPlayer():GetNetworkedBool("infected",false)
		Hazard.Blinded = LocalPlayer():GetNetworkedBool("blinded",false)
		//Hazard.Fire = LocalPlayer():GetNetworkedBool("onfire",false)
		
		if Hazard.Bleeding then
			draw.DrawText("c", "HazInfo", w*(HealthBox.StartX+.005), h*(HealthBox.StartY+(HealthBox.Height*.67)), Hazard.Red,0)
		end
		if Hazard.Infected then
			draw.DrawText("t", "HazInfo", w*(HealthBox.StartX+.006), h*(HealthBox.StartY), Hazard.Green,0)
		end
		if Hazard.Poisoned then
			draw.DrawText("r", "HazInfo", w*(HealthBox.StartX+.072), h*(HealthBox.StartY+.001), Hazard.Purple,0)
		end
		if Hazard.Blinded then
			draw.DrawText("e", "HazInfo", w*(HealthBox.StartX+.072), h*(HealthBox.StartY+(HealthBox.Height*.67)), Hazard.Blue,0)
		end
		
		//PLAYER POINTS
		draw.RoundedBox(0, w*Points.StartX, h*Points.StartY, w*Points.Width, h*Points.Height, HealthBox.Black ) 
		draw.DrawText(GameInfo.PointName.."s: "..LocalPlayer():GetNWInt("points",0), "HudInfoBig", w*((Points.Width*.2)+.05), h*(Points.StartY+.005), color_white,1)
		
		//AMMO, INVENTORY, AND STAMINA METERS
		draw.RoundedBox(0, w*Meters.Ammo.StartX, h*Meters.Ammo.StartY, w*Meters.Ammo.Width, h*Meters.Ammo.Height, HealthBox.Black ) 
		draw.RoundedBox(0, w*Meters.Stam.StartX, h*Meters.Stam.StartY, w*Meters.Stam.Width, h*Meters.Stam.Height, HealthBox.Black ) 
		draw.RoundedBox(0, w*Meters.Inv.StartX, h*Meters.Inv.StartY, w*Meters.Inv.Width, h*Meters.Inv.Height, HealthBox.Black ) 
		
		local stam = LocalPlayer():GetNWInt( "stamina",0 )
		local invslots = LocalPlayer():GetNWInt( "invslots",0 )
		local inv = LocalPlayer():GetNWInt( "weight",0 )
		
		local ammo = 0
		local maxammo = 0
		local ammotype = "none"
		local totalammo = 0
		if LocalPlayer():GetActiveWeapon() != NULL and LocalPlayer():GetActiveWeapon() != nil then
			totalammo = LocalPlayer():GetNWInt("ammo_"..LocalPlayer():GetActiveWeapon():GetUsedAmmoType())
		end
		
		if LocalPlayer():GetActiveWeapon():IsValid() and LocalPlayer():GetActiveWeapon() != NULL then
			ammotype = LocalPlayer():GetActiveWeapon():GetPrimaryAmmoType()
			if ammotype != "none" then
				ammo = math.Clamp(LocalPlayer():GetActiveWeapon():Clip1(), 0, totalammo)
				maxammo = math.Clamp(LocalPlayer():GetActiveWeapon():GetMaxAmmo(), 0, 9000)
			end
		end
		
		local ammosize = math.min(((w*Meters.Ammo.Width)/ maxammo)*ammo,(w*Meters.Ammo.Width))
		local stamsize = math.min(((w*Meters.Stam.Width)/ 100)*stam,(w*Meters.Stam.Width))
		local invsize = math.min(((w*Meters.Inv.Width)/ invslots)*inv,(w*Meters.Inv.Width))
		
		draw.RoundedBox(0, w*Meters.Ammo.StartX, h*Meters.Ammo.StartY, ammosize, h*Meters.Ammo.Height, Meters.Ammo.Color) 
		draw.RoundedBox(0, w*Meters.Inv.StartX, h*Meters.Inv.StartY, invsize, h*Meters.Inv.Height, Meters.Inv.Color) 
		draw.RoundedBox(0, w*Meters.Stam.StartX, h*Meters.Stam.StartY, stamsize, h*Meters.Stam.Height, Meters.Stam.Color) 
		
		draw.DrawText("Inventory:  "..inv.." / "..invslots, "HudInfo", w*(Meters.Inv.StartX + .01), h*(Meters.Inv.StartY + .001), color_white,0)
		draw.DrawText("Stamina:  "..stam.." / 100", "HudInfo", w*(Meters.Stam.StartX + .01), h*(Meters.Stam.StartY + .001), color_white,0)
		draw.DrawText("Ammo:  "..ammo.." / "..totalammo, "HudInfo", w*(Meters.Ammo.StartX + .01), h*(Meters.Ammo.StartY + .001), color_white,0)
		
	elseif LocalPlayer():Team() == TEAM_UNDEAD then
	
		if GameInfo.cProps then
			for k,v in pairs(GameInfo.cProps) do
				if v:IsValid() then
					v:Remove()
				end
			end
			GameInfo.cProps = nil
		end
	
		local pos = LocalPlayer():GetNetworkedVector("antidotepos") 
		local sc = pos:ToScreen()
		if sc.visible then
			local dist = math.Round(LocalPlayer():GetPos():Distance(pos) / 16) //16 units per foot
			draw.DrawText("x", "HudInfo", sc.x, sc.y, color_red,1,1)
			draw.DrawText(TimeFormat(CurTime(),CureTime), "HudInfo", sc.x, sc.y + 16, color_white,1,1)
			draw.DrawText(dist.." feet", "HudInfo", sc.x, sc.y + 28, color_white,1,1)
		end
	
		//HEALTH BAR OUTLINE
		draw.RoundedBox(0, w*(ZombieHealth.StartX-.01), h*(ZombieHealth.StartY-.01), w*(ZombieHealth.Width+.02), h*(ZombieHealth.Height+.02), HealthBox.Black2 ) 
			
		local hp = LocalPlayer():Health()
		local hpratio = hp/MaxHealth
		local hpred=255*(1-hpratio)
		local hpgreen=200*hpratio
		local hpblue =20*hpratio
		local hpcolor = Color(hpred,hpgreen,hpblue,150)
			
		local drawwide = math.min(((w*ZombieHealth.Width)/ MaxHealth)*hp,(w*ZombieHealth.Width))
		draw.RoundedBox(0, w*ZombieHealth.StartX, h*ZombieHealth.StartY, drawwide, h*ZombieHealth.Height, hpcolor ) 
			
	end
end
hook.Add( "HUDPaint", "DrawPlayerHUD", HUDPaint )

function TimeScale(cur,maxtime)
	if CurTime() > maxtime then return 1 end
	return math.min((CurTime() - cur) / (maxtime - cur),maxtime)
end

function TimeFormat(CurTime,DesTime)

	if DesTime == nil then return "00:00" end

	if CurTime >= DesTime then return "00:00" end
	local Time = DesTime - CurTime

    local Seconds = Time % 60
    local Minutes = math.floor(Time/60) % 60
    local NewTime = ""
       
    if Minutes < 10 then
        NewTime = NewTime.."0"..Minutes..":"
    else NewTime = NewTime..Minutes..":" end
   
    if Seconds < 10 then
        NewTime = NewTime.."0"..math.floor(Seconds)
    else NewTime = NewTime..math.floor(Seconds) end
   
    return NewTime
end

function HealthBonus(msg)
	ColorModify[ "$pp_colour_addr" ]		= .4
	ColorModify[ "$pp_colour_addb" ]		= .7
	ColorModify[ "$pp_colour_mulb" ] 		= .5
	DrawingTime = CurTime() - 1
end
usermessage.Hook("HealthKit", HealthBonus) 

function HealthTiny(msg)
	ColorModify[ "$pp_colour_addr" ]		= .2
	ColorModify[ "$pp_colour_addb" ]		= .5
	ColorModify[ "$pp_colour_mulb" ] 		= .3
	DrawingTime = CurTime() - 1
end
usermessage.Hook("HealthTiny", HealthTiny) 

function HealthLoss(msg)
	ColorModify[ "$pp_colour_addr" ]		= .8
	ColorModify[ "$pp_colour_addg" ]		= .2
	ColorModify[ "$pp_colour_mulr" ] 		= .7
	DrawingTime = CurTime() - 1
end
usermessage.Hook("HealthLoss", HealthLoss) 

function UpdateMaxHealth( msg )
	MaxHealth = msg:ReadShort()
end
usermessage.Hook("MaxHealth", UpdateMaxHealth) 

function UpdateTime( msg )
local readval = msg:ReadShort()
	GameInfo.STime = readval
end
usermessage.Hook("UpdateTime", UpdateTime) 

function UpdateCureTime( msg )
	local readval = msg:ReadShort()
	CureTime = readval
end
usermessage.Hook("UpdateCureTime", UpdateCureTime) 

function UpdateEvacTime( msg )
	local readval = msg:ReadShort()
	EvacTime = readval
end
usermessage.Hook("UpdateEvacTime", UpdateEvacTime) 

FvoxDelay = 0
function PlaySound( msg )
	local sound = msg:ReadString()
	if string.find(sound,"fvox") then
		if FvoxDelay < CurTime() and ToggleFVOX and LocalPlayer():Alive() then
			LocalPlayer():EmitSound(sound,110,100)
			FvoxDelay = CurTime() + 5
		end
	elseif string.find(sound,"music") or string.find(sound,"lastminute") then
		if not ToggleMusic then
			return 
		else
			if LocalPlayer() then
				LocalPlayer():EmitSound(sound,110,100)
			end
		end
	else
		if LocalPlayer() then
			LocalPlayer():EmitSound(sound,110,100)
		end
	end
end
usermessage.Hook("PlaySound", PlaySound) 

function CMsg( msg )
	Msg(msg:ReadString().."\n")
end
usermessage.Hook("CMsg", CMsg) 

function GiveInfra( msg )
	Infravision = true
end
usermessage.Hook("GiveInfra", GiveInfra) 

function TogglePlay(ply, cmd, args)
	ToggleMusic = not ToggleMusic
	if ToggleMusic == true then 
		Msg("Music toggled on.\n") 
		LocalPlayer():EmitSound("buttons/button3.wav")
	else 
		Msg("Music toggled off.\n")
		LocalPlayer():EmitSound("buttons/weapon_cant_buy.wav")
	end
end
concommand.Add("rd_togglemusic",TogglePlay)

function TogglePPs(ply, cmd, args)
	TogglePP = not TogglePP
	if TogglePP == true then 
		Msg("Post-processing toggled on.\n") 
		LocalPlayer():EmitSound("buttons/button3.wav")
	else 
		Msg("Post-processing toggled off.\n")
		LocalPlayer():EmitSound("buttons/weapon_cant_buy.wav")
	end
end
concommand.Add("rd_togglepp",TogglePPs)

function ToggleF(ply, cmd, args)
	ToggleFVOX = not ToggleFVOX
	if ToggleFVOX == true then 
		Msg("HVOX voice toggled on.\n") 
		LocalPlayer():EmitSound("buttons/button3.wav")
	else 
		Msg("HVOX voice toggled off.\n")
		LocalPlayer():EmitSound("buttons/weapon_cant_buy.wav")
	end
end
concommand.Add("rd_togglevoice",ToggleF)

function ToggleZHUD(ply, cmd, args)
	ToggleHUD = not ToggleHUD
	if ToggleHUD == true then 
		Msg("HUD toggled on.\n") 
		LocalPlayer():EmitSound("buttons/button3.wav")
	else 
		Msg("HUD toggled off.\n")
		LocalPlayer():EmitSound("buttons/weapon_cant_buy.wav")
	end
end
concommand.Add("rd_togglehud",ToggleZHUD)

HelpText = ""
function DrawHelp()
	if not HelpMenuOpen then return end

	local posx = ScrW()/2-300
	local posy = ScrH()/2-180
	
	local tbl = string.Explode("\n",HelpText)

	for k,v in pairs(tbl) do
		draw.SimpleText(v, "HelpText", posx, posy, Color(0,0,0,255),0,1)
		posy = posy + 15
	end

end

hook.Add("HUDPaint", "HelpDraw", DrawHelp)

function TimedSin(freq,min,max,offset)
    return math.sin(freq * math.pi * 2 * CurTime() + offset) * (max-min) * 0.5 + min
end 

GameInfo.cInv = {}
function InvSynch( msg )
	GameInfo.cInv = {}
end
usermessage.Hook("InvSynch", InvSynch) 

function InvInsert( msg )
	table.insert(GameInfo.cInv,msg:ReadString())
end
usermessage.Hook("InvInsert", InvInsert) 

function ClassUnlock( msg )
	//if Unlocked > msg:ReadFloat() then return end
	Unlocked = msg:ReadFloat()
end
usermessage.Hook("UnlockClass", ClassUnlock) 

Options = {}
Options[1] = {Name="Toggle PP", Desc="Toggle all postprocess effects.", Cmd="rd_togglepp"}
Options[2] = {Name="Toggle Music", Desc="Toggle last minute music.", Cmd="rd_togglemusic"}
Options[3] = {Name="Toggle FVOX", Desc="Toggle all FVOX voice sounds.", Cmd="rd_togglevoice"}
Options[4] = {Name="Toggle HUD", Desc="Toggle the zombie HUD.", Cmd="rd_togglehud"}

function OpenOptionsMenu(msg)
	gui.EnableScreenClicker(true)
	local frame = vgui.Create("DFrame")
	frame:SetSize(4,6) //obsolete
	frame:SetPos((ScrW()/4),ScrH()/2-300) 
	frame:SetTitle("Options")
	frame.Close = function() gui.EnableScreenClicker(false) frame:Remove() end
	CurMenu = frame //so we can close it when the player dies
	
	local xpos = 20
	local ypos = 30
	local ytotal = 40

	for k, v in pairs(Options) do
	
		local button = vgui.Create("DButton",frame)
		button:SetText(v.Name)
		button:SetPos(xpos,ypos)
		button.DoClick = function( ) RunConsoleCommand(v.Cmd) end
		
		local label = vgui.Create("DLabel",frame)
		label:SetText(v.Desc)
		label:SetPos(xpos+70,ypos)
		label:SetSize(300,30)
		
		ypos = ypos + 25
		ytotal = ytotal + 25
		
	end
	frame:SetSize(400,ytotal)
end
usermessage.Hook("OptionsMenu", OpenOptionsMenu)

function SetItemToPreview(name)	
	if name == nil or name == "---" then 
		if PreviewProp and PreviewProp:IsValid() then 
			PreviewProp:Remove() 
			PreviewProp = nil
		end
	return 
	end
	local model = "models/weapons/w_shot_xm1014.mdl"
	for k,v in pairs(Inventory.Merchant) do
		if v.Name == name then
			model = v.Model
		end
	end
	if PreviewProp and PreviewProp:IsValid() then PreviewProp:Remove() end
	PreviewProp = ents.Create("prop_physics")
	PreviewProp:SetModel(model)
	PreviewProp:SetPos(LocalPlayer():GetPos())
	PreviewTime = CurTime() + 20
end

PreviewTime = 0
function ItemPreview()
	if WindowOpen then
		if PreviewTime > CurTime() and PreviewProp and PreviewProp:IsValid() then
			PreviewProp:SetPos(LocalPlayer():GetShootPos() + (LocalPlayer():GetAimVector() * 50) + Vector(0,0,-20) )
			PreviewProp:SetAngles(Angle(0,math.NormalizeAngle(TimedSin(0.1,0,360,10)),0))
			local phys = PreviewProp:GetPhysicsObject()
			if phys and phys:IsValid() then
				phys:EnableGravity(false)
			end
			local cl = math.Clamp(TimedSin(0.2,10,320,10),0,250)
			draw.SimpleText(GameInfo.MerchantName, "HudInfoBig", ScrW()*.5, ScrH()*.10, Color(cl,cl,cl,250),1,1)
			draw.SimpleText(GameInfo.MerchantSubtitle, "HudInfoBig", ScrW()*.5, ScrH()*.12, Color(cl,cl,cl,250),1,1)
		else
			if PreviewProp and PreviewProp:IsValid() then
				PreviewProp:Remove()
			end
		end
	end
end
hook.Add("HUDPaint", "GunPrevThink", ItemPreview)

function MerchantMenu( msg )
	WindowOpen = true
	gui.EnableScreenClicker(true)
	BuildVguiMenu(Inventory.Merchant)
end
usermessage.Hook("MerchantMenu", MerchantMenu) 

function MerchantBuy( name )
	PreviewTime = CurTime()
	gui.EnableScreenClicker(false)
	RunConsoleCommand("buyitem",name)
end

//This should be the basic vgui structure to make our life easier
function BuildVguiMenu(tbl)
	
	if tbl == nil then gui.EnableScreenClicker(false) return end

	local frame = vgui.Create("DFrame")
	frame:SetSize(4,6) //obsolete
	frame:SetPos((ScrW()/4),ScrH()/2-300) 
	frame:SetTitle(GameInfo.MerchantName)
	frame.Close = function() gui.EnableScreenClicker(false) frame:Remove() RunConsoleCommand("buyitem",nil) PreviewTime = CurTime() end
	CurMenu = frame //so we can close it when the player dies

	local points = LocalPlayer():GetNWInt("points",0)
	local SelectedItem = nil
	local items = {}
	
	local list = vgui.Create("DListView",frame)
	list:SetPos(10,25)
	
	local c0 = list:AddColumn( "Stock" ) 
	local c1 = list:AddColumn( "Cost" ) 
	local c2 = list:AddColumn( "Item" ) 
	local c3 = list:AddColumn( "Description" ) 
	
	c0:SetMinWidth( 40 )
	c0:SetMaxWidth( 40 )
	c1:SetMinWidth( 30 )
	c1:SetMaxWidth( 30 )
	c2:SetMinWidth( 100 )
	c2:SetMaxWidth( 100 )

	local itemline, ammoline = true, true
	list:AddLine( "---", "---", "-- WEAPONS --", "---------" ) 
	table.insert(items,"---")
	
	for k, v in pairs(tbl) do
	
		if v.Weight and v.Ammo and ammoline then
			list:AddLine( "---", "---", "-- AMMUNITION --", "---------" ) 
			table.insert(items,"---")
			ammoline = false
		elseif v.Weight and not v.Ammo and itemline then
			list:AddLine( "---", "---", "-- ITEMS --", "---------" ) 
			table.insert(items,"---")
			itemline = false
		end
	
		list:AddLine( v.Stock, v.Price, v.Name, v.Desc ) 
		table.insert(items,v.Name)
	
	end
	
	local button = vgui.Create("DButton",frame)
	button:SetText("Exit Menu")
	button:SetPos(10,230)
	button:SetSize(80,30)
	button.DoClick = function() gui.EnableScreenClicker(false) frame:Remove() RunConsoleCommand("buyitem",nil) PreviewTime = CurTime() end
	
	local button2 = vgui.Create("DButton",frame)
	button2:SetText("Buy Selected Item")
	button2:SetPos(100,230)
	button2:SetSize(120,30)
	button2:SetDisabled(true)
	button2.DoClick = function() MerchantBuy(SelectedItem) frame:Remove() end
	
	local label = vgui.Create("DLabel",frame)
	label:SetText("You have "..points.." "..GameInfo.PointName.."s to spend.")
	label:SetPos(230,238)
	label:SetSize(200,15)
	
	list.SortByColumn = function() end
	list.OnRowSelected = function(lineID,line) SetItemToPreview(items[line]) SelectedItem = items[line] button2:SetDisabled(ItemNotAvailable(items[line])) end
	
	list:SetSize(540, 200) 
	frame:SetSize(560,280)
end

function ItemNotAvailable(name)
	local points = LocalPlayer():GetNWInt("points",0)
	for k,v in pairs(Inventory.Merchant) do
		if v.Name == name then
			if points < v.Price then return true end
			return v.Stock <= 0
		end
	end
	return true
end

function ReduceStock(msg)
	local name = msg:ReadString()
	local amt = msg:ReadShort()
	for k,v in pairs(Inventory.Merchant) do
		if v.Name == name then
			Inventory.Merchant[k].Stock = math.Clamp(amt,0,100)
		end
	end
end
usermessage.Hook("ReduceStock", ReduceStock) 

function ClassCommand( class )
	gui.EnableScreenClicker(false)
	RunConsoleCommand("changeclass",class)
end

function ClassMenu( msg ) //obsolete
	local num = msg:ReadShort() or 1
	//timer.Simple(1,function() ClassVguiMenu(num) end)
	ClassVguiMenu()
	timer.Simple(2,function() gui.EnableScreenClicker(true) end)
end
usermessage.Hook("ClassMenu", ClassMenu) 

function ClassVguiMenu()

	//Girly = table.HasValue(GirlyModels,LocalPlayer():GetNWString("model","models/player/police.mdl"))

	local classtable = HumanClass
	if num == TEAM_UNDEAD or LocalPlayer():Team() == TEAM_UNDEAD then
		classtable = ZombieClass
	end
	gui.EnableScreenClicker(true)

	local frame = vgui.Create("DFrame")
	frame:SetSize(400,600)
	frame:SetPos(ScrW()/2 - 200,ScrH()/2 - 200)
	frame:SetTitle("Class Menu")
	frame.Close = function() 
		if LocalPlayer():Team() == TEAM_UNDEAD then
			frame:Remove() gui.EnableScreenClicker(false)
		end
	end
	frame:MakePopup()
	CurMenu = frame //so we can close it when the player dies
	local xpos = 20
	local ypos = 30
	local ytotal = 40

	local av = LocalPlayer():GetNetworkedString("classdisable","Bagel") 
	for k, v in pairs(classtable) do
	
		if v.Unlock then
			if v.Unlock > Unlocked then
				frame:SetSize(400,ytotal)
				return
			end
		end
	
		local button = vgui.Create("DButton",frame)
		button:SetText(v.Name)
		button:SetPos(xpos,ypos)
		button.DoClick = function( ) ClassCommand(v.Name) frame:Remove() end
		if av == v.Name and LocalPlayer():Team() != TEAM_UNDEAD and GameInfo.ClassLimit then
			button:SetDisabled(true)
		end
		
		local text = string.Explode("$",v.Desc)
		
		for k,v in pairs(text) do
			local label = vgui.Create("DLabel",frame)
			label:SetText(v)
			label:SetPos(xpos+70,ypos)
			label:SetSize(300,30)
			ypos = ypos + 15
			ytotal = ytotal + 15
		end
		
		ypos = ypos + 25
		ytotal = ytotal + 25
		
	end
	frame:SetSize(400,ytotal)
end

Awards = {}
function AddAwards( msg )
	local award = msg:ReadString()
	local desc = msg:ReadString()
	local id = msg:ReadString()
	local sound = msg:ReadString()
	local score = msg:ReadShort()
	
	local added
	for k,v in pairs(player.GetAll()) do
		if v:Name() == id then
			added = v
		end
	end
	if added then
		Awards[table.Count(Awards) + 1] = {Name=award, Desc=desc, Player=added, Score=score, Sound=sound}
	else
		Awards[table.Count(Awards) + 1] = {Name=award, Desc=desc, Player=nil, Score=0, Sound=sound}
	end
end
usermessage.Hook("AwardWinner", AddAwards) 

function EndAwards( msg )
	gui.EnableScreenClicker(true)
	AwardVguiMenu(Awards)
end
usermessage.Hook("AwardsEnd", EndAwards) 

function FindAwardTable(name)
	for k,v in pairs(Awards) do
		if v.Name == name then
			return v
		end	
	end
	return nil
end

function AwardVguiMenu(tbl)
	if tbl == nil then gui.EnableScreenClicker(false) return end

	local frame = vgui.Create("DFrame")
	frame:SetSize(4,6) //obsolete
	frame:SetPos((ScrW()/4),ScrH()/2-300) 
	frame:SetTitle("Carnage Report")
	frame.Close = function() gui.EnableScreenClicker(false) frame:Remove() end

	local SelectedItem = nil
	local items = {}
	
	local list = vgui.Create("DListView",frame)
	list:SetPos(10,25)
	
	local c0 = list:AddColumn( "Award" ) 
	local c1 = list:AddColumn( "Description" ) 
	
	c0:SetMinWidth( 90 )
	c0:SetMaxWidth( 90 )

	local itemline, ammoline = true, true
	list:AddLine( "-----", "---- WINNERS ----" ) 
	table.insert(items,"---")
	
	for k, v in pairs(tbl) do
		if k == 11 then
			list:AddLine( "-----", "---- ALMOST WINNERS ----" ) 
			table.insert(items,"---")
			ammoline = false
		end
		list:AddLine( v.Name, v.Desc ) 
		table.insert(items,v.Name)
	end
	
	local aimg = vgui.Create("AvatarImage",frame)
	aimg:SetPos(10,240)
	aimg:SetSize(40,40)
	aimg:SetPlayer(LocalPlayer())
	
	local label = vgui.Create("DLabel",frame)
	label:SetText("Select one of the rows to view the winner of each award.")
	label:SetPos(80,250)
	label:SetSize(500,15)
	
	list.SortByColumn = function() end
	list.OnRowSelected = function(lineID,line) 
		local tbl = FindAwardTable(items[line])
		if tbl != nil then
			if tbl.Player != nil and tbl.Player != NULL and tbl.Player:IsValid() then
				label:SetText("The winner of this award is "..tbl.Player:Name().." with a score of "..tbl.Score..".")
				aimg:SetPlayer(tbl.Player)
			else
				label:SetText("This award is non-applicable to any of the players.")
				aimg:SetPlayer(nil)
			end
			LocalPlayer():EmitSound(tbl.Sound)
		else
			label:SetText("Select one of the rows to view the winner of each award.")
			aimg:SetPlayer(LocalPlayer())
		end
	end
	
	list:SetSize(540, 200) 
	frame:SetSize(560,290)
end

HtmlTest = "<br><br> HAI2U <br> <b>SJDSIFSHD <i>ODdsfsdghA</i></b> <marquee>lol marquee</marquee> <br><br> k bye"

function HelpMenu(msg)

	gui.EnableScreenClicker(true)
	
	local frame = vgui.Create("DFrame")
	frame:SetSize(4,6) //obsolete
	frame:SetTitle("Survival Guide")
	frame:SetPos(ScrW()/2 - 330,ScrH()/2 - 300) 
	frame.Close = function() gui.EnableScreenClicker(false) frame:Remove() RunConsoleCommand("closehelpmenu") end
	frame:SetSize(700,660)

	local htm = vgui.Create("HTML",frame)
	htm:SetSize(4,6) //obsolete
	htm:SetPos(20,30) 
	htm:SetSize(660,600)
	htm:OpenURL("http://www.redead.net/redeadhelp")
	//htm:SetHTML(HtmlTest)
end
usermessage.Hook("ShowHelp", HelpMenu) 

function NoHud(name)
	for k, v in pairs{"CHudHealth", "CHudBattery", "CHudAmmo", "CHudSecondaryAmmo"} do
		if name == v then return false end
  	end 
end
hook.Add("HUDShouldDraw", "NoDrawHud", NoHud)
